package com.webserver.core;

import com.webserver.http.HttpServletRequest;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;
import java.net.URISyntaxException;
import java.nio.charset.StandardCharsets;

/**
 * 该线程任务负责处理与某个客户端的一次 HTTP 交互
 * 由于 HTTP 协议要求客户端和服务端采取一问一答的原则,因此这里处理与客户端的一次交互规划为三个步骤:
 * 1,解析请求(将客户端发送过来的请求内容读取)
 * 2,处理请求(根据请求内容进行对应的处理)
 * 3,发送响应(将处理结果回馈给浏览器)
 * 断开连接
 */
public class ClientHandler implements Runnable{
    private Socket socket;
    private static File rootDir;
    private static File staticDir;

    static {
        try {
            rootDir = new File(ClientHandler.class.getClassLoader()
                    .getResource(".").toURI());
            staticDir = new File(rootDir,"static");
        } catch (URISyntaxException e ) {
            e.printStackTrace();
        }
    }

    public ClientHandler(Socket socket) {
        this.socket = socket;
    }

    @Override
    public void run() {
        try{
            // 1 : 解析请求(将客户端发送过来的请求内容读取到)
            HttpServletRequest request = new HttpServletRequest(socket);
            // 2 : 处理请求(根据请求内容进行对应的处理)
            String path = request.getUri();
            // 3 : 发送响应(将处理结果回馈给浏览器)
            File file = new File(staticDir,path);
            System.out.println("文件是否存在:"+ file.exists());
            OutputStream out = socket.getOutputStream();
            // 发送状态行  HTTP/1.1 200 OK
            println("HTTP/1.1 200 OK");
            // 发送响应头  Content-Type: text/html(CRLF)
            println("Content-Type: text/html");
            // Content-Length: 2546(CRLF)
            println("Content-Length: " + file.length());
            // 单独发送回车+换行表达响应头发送完毕
            println("");

            //发送响应正文
            // 将 index.html文件所有数据发送
            FileInputStream fis = new FileInputStream(file);
            byte[] data = new byte[1024*10];
            int len;
            while ((len = fis.read(data)) != -1) {
                out.write(data,0,len);
            }


        } catch (IOException e ) {
            e.printStackTrace();
        } finally {
            // 按照 HTTP 协议要求,处理最后要断开连接
            try {
                socket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    private void println(String line) throws IOException {
        OutputStream os = socket.getOutputStream();
        os.write(line.getBytes(StandardCharsets.UTF_8));
        os.write(13);
        os.write(10);
    }

}
